//
// Created by XML on 2023/9/24.
//
#include "io_utils.h"
#include <stdlib.h>
#include <time.h>

#define ARRAY_SIZE 10

void array_init();

void array_limit();

int sum_int_array();

void array_params();

void sum_int_array2d();

void array2d();

void shuffle_array();

void swap_elements(int array[], int first, int second);

int main(){
    // 数组初始化
//    array_init();

    // 数组边界
//    array_limit();

// 数组作为形参
//    array_params();

// 二维数组
//    array2d();

// 实战: 打乱数组元素与快排
    shuffle_array();


    return 0;
}

int partition(int array[],int low ,int high){
    // 选择最后一个元素为 中间位元素
    int pivot = array[high];
    int partition = low;// 默认从低位开始
    for (int i = low; i < high; ++i) {
        if(array[i] < pivot){
            swap_elements(array,i,partition);
            partition++;
        }
    }
    swap_elements(array,pivot,high);
    return partition;

}

void quick_sort(int array[], int low, int high) {
    if (low >= high) return;
    // 查找分割点
    int p = partition(array, low, high);
    // p点的左边
    quick_sort(array, low, p - 1);
    // p点的右边
    quick_sort(array, p + 1, high);

}

void shuffle_array() {
// C语言随机函数：rand（）和srand()  https://blog.csdn.net/qq_43516928/article/details/118864806
    int array[ARRAY_SIZE] ={0};
    for (int i = 0; i < ARRAY_SIZE; ++i) {
        array[i] = i;
    }
    PRINT_INT_ARRAY(array, ARRAY_SIZE);
    srand(time(NULL));
    for (int i = 0; i < ARRAY_SIZE; ++i) {
        int random_number = rand() % ARRAY_SIZE;

        // 交换数组元素
        swap_elements(array, i, random_number);

    }
    PRINT_INT_ARRAY(array, ARRAY_SIZE);

    PRINTLNF("===排序后===");
    quick_sort(array, 0, ARRAY_SIZE);

    PRINT_INT_ARRAY(array, ARRAY_SIZE);

}

void swap_elements(int array[], int first, int second) {
    int temp = array[first];
    array[first] = array[second];
    array[second] = temp;
}

void array2d() {
// 二维数组，就是一维数组的元素也是一个数组，
// 相当于一个网格，如下五行四列
    int scores[5][4] = {
            {135, 135, 138, 277},
            {105, 134, 108, 265},
            {113, 107, 145, 232},
            {123, 99, 140, 227},
            {98, 118, 127, 242}
    };

    int result[5] = {0};
    sum_int_array2d(5, 4, scores, result);
    PRINT_INT_ARRAY(result, 5);
}

// 二维数组传参 ，数组长度可以用局部变量声明
void sum_int_array2d(int rows, int columns , int source_array[rows][columns], int result[]){
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < columns; ++j) {
            result[i] += source_array[i][j];
        }
    }
}

void array_params() {
    int array[ARRAY_SIZE] = {1, 4, 7, 0, 10, 33, 654, 392, 23, 43};
    PRINT_INT(sum_int_array(array, 10));

    int smaller_array[5] = {1, 2, 3, 4, 5};
    PRINT_INT(sum_int_array(smaller_array, 5));

    int bigger_array[15] = {3, 6, 4, 7, 0, 10, 33, 654, 6, 4, 7, 0, 10, 33, 654};
    PRINT_INT(sum_int_array(bigger_array, 15));
}

// 数组作为形参，必须指定长度
int sum_int_array(int array[],int length){
    int sum  =0 ;
    for (int i = 0; i <length; ++i) {
        sum += array[i];
    }
    return sum;
}

void array_limit() {// 数组长度10
    int array[ARRAY_SIZE];
    int array_with_expression[3 + 2]; // 长度可以表达式 C99 开始
    PRINT_INT(array[0]); //
    PRINT_INT(array[11]);  // 数组越界不会报错 c99 , 使用中要小心


    // 数组长度可以用变量表示
    int value = 2;
    // C99, VLA; gcc OK; MSVC ERROR
    int array_size_of_value[value];

    const int kSize = 5; // C++ OK
    int array_size_of_const[kSize]; // C99, VLA; gcc OK; MSVC ERROR

}

void array_init() {
    // 声明一个长度10的整型数组类型，空数组
    int array[ARRAY_SIZE];

    // 数组统一初始化默认值
//    int array[ARRAY_SIZE] = {0};

    for (int i = 0; i < ARRAY_SIZE; ++i) {
        array[i] = i; // 元素赋值 set
        PRINT_INT(array[i]); // 获取数组元素 get
    }

    // 在声明时，默认初始化所有元素的数组
    int array2[ARRAY_SIZE] = {0,1,2,3,4,5,6,7,8,9};


    // 声明double数组类型，默认按顺序初始化元素，这个只初始化下标0，1元素
    double array_double[5] = {0.1, 2.3};
    for (int i = 0; i < 5; ++i) {
        PRINT_DOUBLE(array_double[i]);
    }

    // 声明char数组类型，指定某个下标初始值，这里是下标2的初始化值
    char array_char[5] = {[2] = 'o', 'l', 'l'};
    for (int i = 0; i < 5; ++i) {
        PRINT_CHAR(array_char[i]);
    }
}
